package com.gdust.hzx.manager.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.gdust.hzx.manager.mapper.CategoryMapper;
import com.gdust.hzx.model.vo.product.CategoryExcelVo;

import java.util.List;

/**
 * Excel 数据读取监听器
 *
 * 描述：通过 EasyExcel 监听 Excel 文件的读取事件，批量处理数据并将其存储到数据库。
 *
 * @param <T> 数据对象的类型（如 CategoryExcelVo）
 * @Author syun
 * @Create 2024/12/1 21:35
 * @Version 1.0
 */
public class ExcelListener<T> implements ReadListener<T> {

    /**
     * 每次批量存储的记录数，默认为 100
     */
    private static final int BATCH_COUNT = 100;

    /**
     * 缓存读取到的 Excel 数据
     */
    private List<T> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    /**
     * 数据访问对象，用于与数据库交互
     */
    private CategoryMapper categoryMapper;

    /**
     * 构造函数，注入 Mapper 对象
     *
     * @param categoryMapper 用于执行数据库操作的 Mapper 实例
     */
    public ExcelListener(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    /**
     * 每行数据解析后的回调方法
     *
     * 描述：从 Excel 中读取一行数据并将其存入缓存列表。若缓存达到批量存储阈值，则将数据存入数据库。
     *
     * @param t               当前行解析出的数据对象
     * @param analysisContext 上下文对象，包含 Excel 文件的元信息
     */
    @Override
    public void invoke(T t, AnalysisContext analysisContext) {
        // 将当前行数据添加到缓存列表中
        cachedDataList.add(t);

        // 若缓存达到批量存储阈值，则将数据存储到数据库，并清空缓存
        if (cachedDataList.size() >= BATCH_COUNT) {
            saveData();
            cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }

    /**
     * 所有数据解析完成后的回调方法
     *
     * 描述：在解析完成后，将剩余缓存中的数据存储到数据库。
     *
     * @param analysisContext 上下文对象
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 保存剩余数据
        saveData();
    }

    /**
     * 保存数据到数据库的方法
     *
     * 描述：将缓存中的数据批量插入到数据库中，并执行类型转换。
     */
    private void saveData() {
        // 将缓存的数据批量插入数据库
        categoryMapper.batchInsert((List<CategoryExcelVo>) cachedDataList);
    }
}
